#pragma once

#define NDEBUG
//#define EX_TAIKO

#define WINVER       0x502
#define _WIN32_WINNT 0x502

#ifndef UNICODE
#  define UNICODE
#endif
#ifndef _UNICODE
#  define _UNICODE
#endif
#include <windows.h>

#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>

#ifndef NDEBUG
#  define logf(...) fprintf(stderr, __VA_ARGS__)
#else
#  define logf(...) ((void) 0)
#endif

#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))

#ifdef min
#  undef min
#endif
#ifdef max
#  undef max
#endif
#define min(x, y) ({                            \
        typeof(x) _min1 = (x);                  \
        typeof(y) _min2 = (y);                  \
        (void) (&_min1 == &_min2);              \
        _min1 < _min2 ? _min1 : _min2; })

#define max(x, y) ({                            \
        typeof(x) _max1 = (x);                  \
        typeof(y) _max2 = (y);                  \
        (void) (&_max1 == &_max2);              \
        _max1 > _max2 ? _max1 : _max2; })

#define min3(x, y, z) ({                        \
        typeof(x) _min1 = (x);                  \
        typeof(y) _min2 = (y);                  \
        typeof(z) _min3 = (z);                  \
        (void) (&_min1 == &_min2);              \
        (void) (&_min1 == &_min3);              \
        _min1 < _min2 ? (_min1 < _min3 ? _min1 : _min3) : \
                (_min2 < _min3 ? _min2 : _min3); })

#define max3(x, y, z) ({                        \
        typeof(x) _max1 = (x);                  \
        typeof(y) _max2 = (y);                  \
        typeof(z) _max3 = (z);                  \
        (void) (&_max1 == &_max2);              \
        (void) (&_max1 == &_max3);              \
        _max1 > _max2 ? (_max1 > _max3 ? _max1 : _max3) : \
                (_max2 > _max3 ? _max2 : _max3); })


struct result_t
{
    char flag, flag_prev, flag_next, flag_ui; // o<>,+-.m  a~l
    double status;
    clock_t begin;

    int dx, dy;
    double fps;
} typedef result_t;


/*
 *            o              empty mode
 *            < >            page down/up || next item
 *            ,              clap mode (first clap)
 *            + -            zoom in/out
 *            .              enter/exit (double clap)
 *            m              drag mode
 *            
 *            a~l            to extend
 */
